package org.web.standardplatform.client.builder;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.web.standardplatform.client.domain.attribute.AttributeDTO;
import org.web.standardplatform.client.domain.attribute.ColumnAttributeDTO;
import org.web.standardplatform.client.domain.attribute.JavaAttributeDTO;
import org.web.standardplatform.client.helper.view.select.PatternValueLabelParser;
import org.web.standardplatform.client.helper.view.select.SelectTypeConstant;
import org.web.standardplatform.client.domain.attribute.type.EditType;
import org.web.standardplatform.client.domain.attribute.type.SelectorType;
import org.web.standardplatform.client.domain.attribute.view.SearchFormFieldDefinition;
import org.web.standardplatform.client.domain.attribute.view.TableFieldDefinition;
import org.web.standardplatform.client.domain.attribute.view.TransferViewSettingDTO;
import org.web.standardplatform.client.domain.buildcode.BuildCodeRequest;
import org.web.standardplatform.client.domain.buildcode.CodeClassNameDTO;
import org.web.standardplatform.client.helper.AnnotationMinMaxExtractor;
import org.web.standardplatform.client.helper.view.RuleValidatorBuilder;
import org.web.standardplatform.client.helper.view.rules.TsObjectArrayBuilder;

import java.io.*;
import java.util.List;

public class MainBuildInitViewBuilder implements SelectTypeConstant {


    public static void main(String[] args) throws Exception {
        String fileName = "D:\\test33.xlsx";

        String tableName = getTableName(fileName);
        BuildCodeRequest buildCodeRequest = new BuildCodeRequest();
        buildCodeRequest.setDbType("mysql");
        List<AttributeDTO> attributeList = MainBuildCodeBuilder.getAttributeListForParseExcel(fileName, tableName);
        buildCodeRequest.setAttributeDTOList(attributeList);
        MainBuildCodeBuilder.buildBuildCodeRequestListByExcel(buildCodeRequest, fileName, tableName);
        initViewSetting(buildCodeRequest, fileName, tableName);

        System.out.println("build code success");
    }

    public static String getTableName(String fileName) throws IOException {
        File file = new File(fileName);
        FileInputStream fis = new FileInputStream(file);
        Workbook workbook = new XSSFWorkbook(fis);
        String tableName = workbook.getSheetAt(3).getSheetName();
        fis.close();
        return tableName;
    }

    public static void initViewSetting(BuildCodeRequest buildCodeRequest, String fileName, String tableName) throws Exception {

        for (AttributeDTO attributeDTO : buildCodeRequest.getAttributeDTOList()) {
            buildViewDefaultSetting(attributeDTO);
        }

        File file = new File(fileName);
        FileInputStream inputStream = new FileInputStream(file);
        Workbook workbook = new XSSFWorkbook(inputStream);
        Sheet viewSheet = workbook.getSheet("view");
        int beginRowNum = 2;
        for (AttributeDTO attributeDTO : buildCodeRequest.getAttributeDTOList()) {
            if (attributeDTO.getTransferViewSettingDTO().getSelectorType() == null || SelectorType.NOT_SET == attributeDTO.getTransferViewSettingDTO().getSelectorType()) {
                continue;
            }

            int lastRowNum = viewSheet.getLastRowNum();
            if (lastRowNum >= beginRowNum) {
                viewSheet.shiftRows(beginRowNum, lastRowNum, 1);
            }

            Row row = viewSheet.createRow(beginRowNum);
            row.createCell(0).setCellValue(beginRowNum - 1);
            row.createCell(1).setCellValue(attributeDTO.getColumnAttribute().getShortName());
            row.createCell(2).setCellValue(attributeDTO.getSearchFormFieldDefinition().getQueryAttributeName());
            row.createCell(3).setCellValue(attributeDTO.getSearchFormFieldDefinition().getQueryEditType());
            row.createCell(4).setCellValue(attributeDTO.getSearchFormFieldDefinition().getQueryAttributePlaceholder());
            if (attributeDTO.getSearchFormFieldDefinition().getIsDefaultHidden() != null) {
                row.createCell(5).setCellValue(attributeDTO.getSearchFormFieldDefinition().getIsDefaultHidden());
            }
            // row.createCell(6).setCellValue("");
            if (attributeDTO.getSearchFormFieldDefinition().getRules() != null) {
                row.createCell(7).setCellValue(attributeDTO.getSearchFormFieldDefinition().getRules());
            }
            if (attributeDTO.getSearchFormFieldDefinition().getEditTypeOperateExtend() != null) {
                row.createCell(8).setCellValue(attributeDTO.getSearchFormFieldDefinition().getEditTypeOperateExtend());
            }
            CodeClassNameDTO codeClassNameDTO = new CodeClassNameDTO(tableName);
            //row.createCell(9).setCellValue(codeClassNameDTO.getQueryDTOObjectName());
            row.createCell(10).setCellValue(codeClassNameDTO.getDtoObjectName());
            row.createCell(11).setCellValue(attributeDTO.getJavaAttribute().getAttributeName());

            beginRowNum++;
        }

        // 开始设置table列表信息
        int separatorRowsNum = 4;
        int beginNum = 1;
        for (AttributeDTO attributeDTO : buildCodeRequest.getAttributeDTOList()) {
            Row row = viewSheet.createRow(beginRowNum + separatorRowsNum);
            row.createCell(0).setCellValue(beginNum);
            row.createCell(1).setCellValue(attributeDTO.getColumnAttribute().getShortName());
            row.createCell(2).setCellValue(attributeDTO.getJavaAttribute().getAttributeName());
            row.createCell(3).setCellValue(attributeDTO.getTableFieldDefinition().getEditType());
            row.createCell(4).setCellValue(beginNum);
            if (attributeDTO.getTableFieldDefinition().getIsDefaultHidden() != null) {
                row.createCell(5).setCellValue(true);
            }
            if (attributeDTO.getColumnAttribute().getShortComment() != null) {
                row.createCell(6).setCellValue(attributeDTO.getColumnAttribute().getShortComment());
            }

            if (attributeDTO.getTableFieldDefinition().getRules() != null) {
                row.createCell(7).setCellValue(attributeDTO.getTableFieldDefinition().getRules());
            }

            if (attributeDTO.getTableFieldDefinition().getIsSortable() != null) {
                row.createCell(8).setCellValue(attributeDTO.getTableFieldDefinition().getIsSortable());
            }
            /*
             * 第9,是columnWidth， 指定列宽。
             * 第10，是extendsAttributeInfo，指定扩展信息。
             */
            if (!SqlConverterHelper.judgeColumnNotContainEnum(attributeDTO.getColumnAttribute().getDetailComment())) {
                // 枚举类型设置默认的展示方法。
                row.createCell(10).setCellValue("{\n" +
                        "      formatterFunction: selectColumnFormatter\n" +
                        "    }");
            }

            if (attributeDTO.getTableFieldDefinition().getUnInsertable() != null) {
                row.createCell(11).setCellValue(attributeDTO.getTableFieldDefinition().getUnInsertable());
            }

            if (attributeDTO.getTableFieldDefinition().getUnUpdatable() != null) {
                row.createCell(12).setCellValue(attributeDTO.getTableFieldDefinition().getUnUpdatable());
            }

            if (attributeDTO.getTableFieldDefinition().getEditTypeOperateExtend() != null) {
                row.createCell(13).setCellValue(attributeDTO.getTableFieldDefinition().getEditTypeOperateExtend());
            }

            row.createCell(14).setCellValue(tableName);
            row.createCell(15).setCellValue(attributeDTO.getJavaAttribute().getAttributeName());


            beginNum++;
            beginRowNum++;
        }


        FileOutputStream outputStream = new FileOutputStream(fileName);
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();

    }

    /**
     * 初始化查询条件和table列表信息。
     */
    public static void buildViewDefaultSetting(AttributeDTO attributeDTO) {
        JavaAttributeDTO javaAttributeDTO = attributeDTO.getJavaAttribute();
        ColumnAttributeDTO columnAttributeDTO = attributeDTO.getColumnAttribute();
        TransferViewSettingDTO transferViewSettingDTO = attributeDTO.getTransferViewSettingDTO();
        SearchFormFieldDefinition searchFormFieldDefinition = new SearchFormFieldDefinition();
        searchFormFieldDefinition.setQueryAttributeName(javaAttributeDTO.getAttributeName());
        TableFieldDefinition tableFieldDefinition = new TableFieldDefinition();
        tableFieldDefinition.setAttributeLabel(columnAttributeDTO.getShortName());
        tableFieldDefinition.setAttributeName(javaAttributeDTO.getAttributeName());
        attributeDTO.setSearchFormFieldDefinition(searchFormFieldDefinition);
        attributeDTO.setTableFieldDefinition(tableFieldDefinition);
        boolean needSetAgain = true;

        /*
          优先处理保留字段，如主键、创建时间、修改时间，逻辑删除等。
          */
        if (columnAttributeDTO.isPrimaryKey()) {
            searchFormFieldDefinition.setSelectorType(SelectorType.NOT_SET);
            tableFieldDefinition.setIsSortable(null);
            tableFieldDefinition.setIsDefaultHidden(true);
            tableFieldDefinition.setEditType(EditType.text.name());
            tableFieldDefinition.setUnInsertable(true);
            tableFieldDefinition.setUnUpdatable(true);
            needSetAgain = false;
        }

//        if (tableInfoDTO.getForeignColumnList().contains(columnAttributeDTO.getColumnName())) {
//            viewAttributeDTO.setSelectorType(SupportedSelectorType.NONE);
//            viewAttributeDTO.setTableShowType(ShowType.HIDDEN);
//            viewAttributeDTO.setIsSortable(null);
//            viewAttributeDTO.setEditType("text");
//            needSetAgain = false;
//        }

        if (SqlConverterHelper.hasStr(attributeDTO.getColumnName(), SqlConverterHelper.CREATE_TIME) || SqlConverterHelper.hasStr(attributeDTO.getColumnName(), SqlConverterHelper.UPDATE_TIME)) {
            searchFormFieldDefinition.setSelectorType(SelectorType.COMPARE);
            searchFormFieldDefinition.setQueryEditType(EditType.datetime_range.name());

            tableFieldDefinition.setIsSortable(true);
            tableFieldDefinition.setEditType(EditType.text.name());
            tableFieldDefinition.setUnInsertable(true);
            tableFieldDefinition.setUnUpdatable(true);
            needSetAgain = false;
        }

        if ("is_delete".equalsIgnoreCase(columnAttributeDTO.getColumnName())) {
            searchFormFieldDefinition.setSelectorType(SelectorType.NOT_SET);
            tableFieldDefinition.setIsDefaultHidden(true);
            tableFieldDefinition.setEditType(EditType.text.name());
            tableFieldDefinition.setUnInsertable(true);
            tableFieldDefinition.setUnUpdatable(true);
            needSetAgain = false;
        }

        if (!needSetAgain) {
            return;
        }

        TsObjectArrayBuilder tableColumnRules = TsObjectArrayBuilder.create();
        TsObjectArrayBuilder searchColumnRules = TsObjectArrayBuilder.create();


        if (javaAttributeDTO.getAttributeType().equals("Integer") || javaAttributeDTO.getAttributeType().equals("Long")) {
            String numberPlaceholder = "只能输入数值";
            if (SelectorType.EQUAL == transferViewSettingDTO.getSelectorType()) {
                numberPlaceholder = numberPlaceholder + ",精确匹配。";
            } else if (SelectorType.FUZZY == transferViewSettingDTO.getSelectorType()) {
                numberPlaceholder = numberPlaceholder + ",模糊匹配。";
            }
            searchFormFieldDefinition.setQueryAttributePlaceholder(numberPlaceholder);

            tableFieldDefinition.setEditType(EditType.number.name());
            searchFormFieldDefinition.setQueryEditType(EditType.number.name());
            AnnotationMinMaxExtractor.MinMaxResult minMaxResult = AnnotationMinMaxExtractor.extract(attributeDTO.getJavaAttribute().getDtoRuleList());
            if (minMaxResult.getMaxValue() != null || minMaxResult.getMinValue() != null) {
                Integer min = minMaxResult.getMinValue();
                Integer max = minMaxResult.getMaxValue();

                String value = RuleValidatorBuilder.buildNumberRangeValidator(attributeDTO.getColumnAttribute().getShortName(), min, max);

                tableColumnRules.addItem().field("validator", value, true).end();
                searchColumnRules.addItem().field("validator", value, true).end();
            }

        } else if (javaAttributeDTO.getAttributeType().equals("Date")) {
            tableFieldDefinition.setEditType(EditType.date_range.name());
            searchFormFieldDefinition.setSelectorType(SelectorType.COMPARE);
            searchFormFieldDefinition.setQueryEditType(EditType.datetime_range.name());
        } else {
            if ("LONGTEXT".equalsIgnoreCase(columnAttributeDTO.getColumnType())) {
                tableFieldDefinition.setEditType(EditType.textarea.name());
            } else {
                tableFieldDefinition.setEditType(EditType.text.name());
            }
            if (transferViewSettingDTO.getSelectorType() != null) {
                searchFormFieldDefinition.setQueryEditType(EditType.text.name());
                searchFormFieldDefinition.setSelectorType(transferViewSettingDTO.getSelectorType());
                if (SelectorType.EQUAL == transferViewSettingDTO.getSelectorType()) {
                    searchFormFieldDefinition.setQueryAttributePlaceholder("精确匹配");
                } else if (SelectorType.FUZZY == transferViewSettingDTO.getSelectorType()) {
                    searchFormFieldDefinition.setQueryAttributePlaceholder("模糊匹配");
                    searchFormFieldDefinition.setQueryAttributeName(javaAttributeDTO.getFuzzyQueryAttributeName());
                } else if (SelectorType.IN == transferViewSettingDTO.getSelectorType()) {
                    searchFormFieldDefinition.setQueryEditType(EditType.select.name());
                    searchFormFieldDefinition.setQueryAttributeName(javaAttributeDTO.getInQueryAttributeName());
                    String selectExtendValue = PatternValueLabelParser.parseAttributeForSelect(attributeDTO);
                    searchFormFieldDefinition.setEditTypeOperateExtend(selectExtendValue);
                }
            }
        }


        if ("N".equalsIgnoreCase(String.valueOf(attributeDTO.getColumnAttribute().getAllowNull()))) {
            if (!isProhibitSetWhenUpdate(attributeDTO)) {
                tableColumnRules.addItem().field("required", true).field("message", attributeDTO.getColumnAttribute().getShortName() + "不能为空。").end();
            }
        }

        if (SelectorType.IN != attributeDTO.getTransferViewSettingDTO().getSelectorType() && attributeDTO.getJavaAttribute().getAttributeType().equals("String")) {
            if (attributeDTO.getColumnAttribute().getColumnLength() != null) {
                int maxLength = Integer.parseInt(attributeDTO.getColumnAttribute().getColumnLength());
                tableColumnRules.addItem().field("type", "string").field("max", maxLength).field("message", attributeDTO.getColumnAttribute().getShortName() + "长度不能超过" + maxLength + "个字符。").end();
                searchColumnRules.addItem().field("type", "string").field("max", maxLength).field("message", attributeDTO.getColumnAttribute().getShortName() + "长度不能超过" + maxLength + "个字符。").end();
            }
        }

        if (SelectorType.IN == attributeDTO.getTransferViewSettingDTO().getSelectorType()) {
            attributeDTO.getSearchFormFieldDefinition().setQueryEditType(EditType.select.name());
            attributeDTO.getTableFieldDefinition().setEditType(EditType.select.name());
            String selectExtendValue = PatternValueLabelParser.parseAttributeForSelect(attributeDTO);
            attributeDTO.getTableFieldDefinition().setEditTypeOperateExtend(selectExtendValue);
        }

        if (isProhibitSetWhenUpdate(attributeDTO)) {
            attributeDTO.getTableFieldDefinition().setUnUpdatable(true);
        }


        if (isProhibitSetWhenInsert(attributeDTO)) {
            attributeDTO.getTableFieldDefinition().setUnInsertable(true);
        }


        if (!tableColumnRules.getItems().isEmpty()) {
            tableFieldDefinition.setRules(buildRules(tableColumnRules.buildAsField("rules")));
        }

        if (!searchColumnRules.getItems().isEmpty()) {
            searchFormFieldDefinition.setRules(buildRules(searchColumnRules.buildAsField("rules")));
        }

    }

    public static Boolean isProhibitSetWhenUpdate(AttributeDTO attributeDTO) {
        JavaAttributeDTO javaAttributeDTO = attributeDTO.getJavaAttribute();
        if (javaAttributeDTO.getDtoRuleList() != null) {
            for (String rule : javaAttributeDTO.getDtoRuleList()) {
                if (rule.startsWith("@Null") && rule.contains("UpdateGroup.class")) {
                    return true;
                }
            }
        }
        return false;
    }

    public static Boolean isProhibitSetWhenInsert(AttributeDTO attributeDTO) {
        JavaAttributeDTO javaAttributeDTO = attributeDTO.getJavaAttribute();
        if (javaAttributeDTO.getDtoRuleList() != null) {
            for (String rule : javaAttributeDTO.getDtoRuleList()) {
                if (rule.startsWith("@Null") && rule.contains("InsertGroup.class")) {
                    return true;
                }
            }
        }
        return false;
    }

    private static String buildRules(String str) {
        String result = str.replaceFirst("rules: ", "");
        if (result.endsWith(",")) {
            result = result.substring(0, result.length() - 1); // 去掉最后一个逗号
        }
        return result;
    }

}

